]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
St: drop StClickable, add some functionality to StButton
authorDan Winship <danw@gnome.org>
Tue, 25 Jan 2011 21:22:00 +0000 (16:22 -0500)
committerDan Winship <danw@gnome.org>
Mon, 7 Feb 2011 17:45:48 +0000 (12:45 -0500)
For historical reasons, we had both StClickable and StButton, which
were nearly identical. StButton was more widely-used, so keep that and
port all StClickable users to that.

https://bugzilla.gnome.org/show_bug.cgi?id=640583

13 files changed:
data/theme/gnome-shell.css
js/ui/altTab.js
js/ui/appDisplay.js
js/ui/dnd.js
js/ui/endSessionDialog.js
js/ui/panel.js
js/ui/searchDisplay.js
src/Makefile-st.am
src/st/st-button.c
src/st/st-button.h
src/st/st-clickable.c [deleted file]
src/st/st-clickable.h [deleted file]
src/st/st-marshal.list

index 3e7cc8112c510c550abe8a9497fec6560428a4f8..a79b01cc241260fab21faba06a3496669b923f9d 100644 (file)
@@ -217,7 +217,7 @@ StTooltip StLabel {
     transition-duration: 100;
 }
 
-.panel-button:active, .panel-button:checked, .panel-button:pressed, .panel-button:focus {
+.panel-button:active, .panel-button:checked, .panel-button:focus {
     background-gradient-direction: vertical;
     background-gradient-start: #3c3c3c;
     background-gradient-end: #131313;
@@ -541,11 +541,6 @@ StTooltip StLabel {
     transition-duration: 100;
 }
 
-.app-well-app:active > .overview-icon {
-    background-color: #1e1e1e;
-    border: 1px solid #5f5f5f;
-}
-
 .app-well-menu {
     font-size: 12px
 }
index 03b8fdca77a8096339a58f01cfd264404e5f623d..46c2a09bfc0f92ff8e81e486a1d7d90223864053 100644 (file)
@@ -593,8 +593,8 @@ SwitcherList.prototype = {
     },
 
     addItem : function(item) {
-        let bbox = new St.Clickable({ style_class: 'item-box',
-                                      reactive: true });
+        let bbox = new St.Button({ style_class: 'item-box',
+                                   reactive: true });
 
         bbox.set_child(item);
         this._list.add_actor(bbox);
index c5fe8c6a6b926c51562f7aa9e0d874c63bdcb6d2..4628a5a7a1b73feb96baa27baa4e605d492c98df 100644 (file)
@@ -319,10 +319,11 @@ function AppWellIcon(app, iconParams) {
 AppWellIcon.prototype = {
     _init : function(app, iconParams) {
         this.app = app;
-        this.actor = new St.Clickable({ style_class: 'app-well-app',
-                                         reactive: true,
-                                         x_fill: true,
-                                         y_fill: true });
+        this.actor = new St.Button({ style_class: 'app-well-app',
+                                     reactive: true,
+                                     button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
+                                     x_fill: true,
+                                     y_fill: true });
         this.actor._delegate = this;
 
         this.icon = new AppIcon(app, iconParams);
@@ -390,12 +391,11 @@ AppWellIcon.prototype = {
         return false;
     },
 
-    _onClicked: function(actor, event) {
+    _onClicked: function(actor, button) {
         this._removeMenuTimeout();
 
-        let button = event.get_button();
         if (button == 1) {
-            this._onActivate(event);
+            this._onActivate(Clutter.get_current_event());
         } else if (button == 2) {
             let newWorkspace = Main.overview.workspaces.addWorkspace();
             if (newWorkspace != null) {
index 71d8c04bc83776996f99695e14343eb18e145db7..7c88dc22a676d1322d28b4f2522ec80f11922172 100644 (file)
@@ -112,11 +112,11 @@ _Draggable.prototype = {
             return false;
 
         this._buttonDown = true;
-        // special case St.Clickable: grabbing the pointer would mess up the
+        // special case St.Button: grabbing the pointer would mess up the
         // internal state, so we start the drag manually on hover change
-        if (this.actor instanceof St.Clickable)
+        if (this.actor instanceof St.Button)
             this.actor.connect('notify::hover',
-                               Lang.bind(this, this._onClickableHoverChanged));
+                               Lang.bind(this, this._onButtonHoverChanged));
         else
             this._grabActor();
 
@@ -127,8 +127,8 @@ _Draggable.prototype = {
         return false;
     },
 
-    _onClickableHoverChanged: function(button) {
-        if (button.hover || !button.held)
+    _onButtonHoverChanged: function(button) {
+        if (button.hover || !button.pressed)
             return;
 
         button.fake_release();
index c25633ac22340b155cbfe3a1edd42848a79d9373..6b85bd87f391e392a551e3c03bb060302d9ffa3b 100644 (file)
@@ -137,12 +137,12 @@ ListItem.prototype = {
 
         let layout = new St.BoxLayout({ vertical: false});
 
-        this.actor = new St.Clickable({ style_class: 'end-session-dialog-app-list-item',
-                                        can_focus:   true,
-                                        child:       layout,
-                                        reactive:    true,
-                                        x_align:     St.Align.START,
-                                        x_fill:      true });
+        this.actor = new St.Button({ style_class: 'end-session-dialog-app-list-item',
+                                     can_focus:   true,
+                                     child:       layout,
+                                     reactive:    true,
+                                     x_align:     St.Align.START,
+                                     x_fill:      true });
 
         this._icon = this._app.create_icon_texture(_ITEM_ICON_SIZE);
 
index 9b7c3b36aa156bdae1c0fa70a3120d59d75a4e0e..4d0e00145c1152a870e8291f58d061ea371caa9c 100644 (file)
@@ -612,10 +612,10 @@ Panel.prototype = {
         /* Button on the left side of the panel. */
         /* Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview". */
         let label = new St.Label({ text: _("Activities") });
-        this.button = new St.Clickable({ name: 'panelActivities',
-                                         style_class: 'panel-button',
-                                         reactive: true,
-                                         can_focus: true });
+        this.button = new St.Button({ name: 'panelActivities',
+                                      style_class: 'panel-button',
+                                      reactive: true,
+                                      can_focus: true });
         this.button.set_child(label);
         this.button._delegate = this.button;
         this.button._xdndTimeOut = 0;
@@ -712,7 +712,7 @@ Panel.prototype = {
         // We get into the Overview mode on button-press-event as opposed to button-release-event because eventually we'll probably
         // have the Overview act like a menu that allows the user to release the mouse on the activity the user wants
         // to switch to.
-        this.button.connect('clicked', Lang.bind(this, function(b, event) {
+        this.button.connect('clicked', Lang.bind(this, function(b) {
             if (!Main.overview.animationInProgress) {
                 this._maybeToggleOverviewOnClick();
                 return true;
@@ -724,10 +724,10 @@ Panel.prototype = {
         // pressing the System key, Alt+F1 or Esc. We want the button to be pressed in when the Overview is entered
         // and to be released when it is exited regardless of how it was triggered.
         Main.overview.connect('showing', Lang.bind(this, function() {
-            this.button.active = true;
+            this.button.checked = true;
         }));
         Main.overview.connect('hiding', Lang.bind(this, function() {
-            this.button.active = false;
+            this.button.checked = false;
         }));
 
         Main.chrome.addActor(this.actor, { visibleInOverview: true });
index 3ed60ad5e824af2471a99e5546a6606c472435b7..44794f6a9b1141acfd54ba426a03cc223214e9db 100644 (file)
@@ -24,10 +24,10 @@ SearchResult.prototype = {
     _init: function(provider, metaInfo, terms) {
         this.provider = provider;
         this.metaInfo = metaInfo;
-        this.actor = new St.Clickable({ style_class: 'search-result',
-                                        reactive: true,
-                                        x_align: St.Align.START,
-                                        y_fill: true });
+        this.actor = new St.Button({ style_class: 'search-result',
+                                     reactive: true,
+                                     x_align: St.Align.START,
+                                     y_fill: true });
         this.actor._delegate = this;
 
         let content = provider.createResultActor(metaInfo, terms);
@@ -69,7 +69,7 @@ SearchResult.prototype = {
         Main.overview.toggle();
     },
 
-    _onResultClicked: function(actor, event) {
+    _onResultClicked: function(actor) {
         this.activate();
     },
 
@@ -221,23 +221,23 @@ SearchResults.prototype = {
     },
 
     _createOpenSearchProviderButton: function(provider) {
-        let clickable = new St.Clickable({ style_class: 'dash-search-button',
-                                           reactive: true,
-                                           x_fill: true,
-                                           y_align: St.Align.MIDDLE });
+        let button = new St.Button({ style_class: 'dash-search-button',
+                                     reactive: true,
+                                     x_fill: true,
+                                     y_align: St.Align.MIDDLE });
         let bin = new St.Bin({ x_fill: false,
                                x_align:St.Align.MIDDLE });
-        clickable.connect('clicked', Lang.bind(this, function() {
+        button.connect('clicked', Lang.bind(this, function() {
             this._openSearchSystem.activateResult(provider.id);
         }));
         let title = new St.Label({ text: provider.name,
                                    style_class: 'dash-search-button-label' });
 
         bin.set_child(title);
-        clickable.set_child(bin);
-        provider.actor = clickable;
+        button.set_child(bin);
+        provider.actor = button;
 
-        this._searchProvidersBox.add(clickable);
+        this._searchProvidersBox.add(button);
     },
 
     createProviderMeta: function(provider) {
index cb54ef4ba0585b0c3ac1c80a5afe13d441bc581c..ffeeb21b8361a68b6de3ee6ee8c56a67d141f3a1 100644 (file)
@@ -72,7 +72,6 @@ st_source_h =                                 \
        st/st-box-layout.h                      \
        st/st-box-layout-child.h                \
        st/st-button.h                          \
-       st/st-clickable.h                       \
        st/st-clipboard.h                       \
        st/st-container.h                       \
        st/st-drawing-area.h                    \
@@ -130,7 +129,6 @@ st_source_c =                                       \
        st/st-box-layout.c                      \
        st/st-box-layout-child.c                \
        st/st-button.c                          \
-       st/st-clickable.c                       \
        st/st-clipboard.c                       \
        st/st-container.c                       \
        st/st-drawing-area.c                    \
index dfee0265ecaa3949e62657fff96c83938a0e4f3e..c3eca6118bc7d3463086846c506d06fac662b8e9 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "st-button.h"
 
+#include "st-enum-types.h"
 #include "st-marshal.h"
 #include "st-texture-cache.h"
 #include "st-private.h"
@@ -49,8 +50,10 @@ enum
   PROP_0,
 
   PROP_LABEL,
+  PROP_BUTTON_MASK,
   PROP_TOGGLE_MODE,
-  PROP_CHECKED
+  PROP_CHECKED,
+  PROP_PRESSED
 };
 
 enum
@@ -65,14 +68,16 @@ enum
 
 struct _StButtonPrivate
 {
-  gchar            *text;
+  gchar *text;
 
-  guint             is_pressed : 1;
-  guint             is_checked : 1;
-  guint             is_toggle : 1;
-  guint             has_grab : 1;
+  guint  button_mask : 3;
+  guint  is_toggle   : 1;
 
-  gint              spacing;
+  guint  pressed     : 3;
+  guint  grabbed     : 3;
+  guint  is_checked  : 1;
+
+  gint   spacing;
 };
 
 static guint button_signals[LAST_SIGNAL] = { 0, };
@@ -119,31 +124,32 @@ st_button_style_changed (StWidget *widget)
 }
 
 static void
-st_button_press (StButton *button)
+st_button_press (StButton     *button,
+                 StButtonMask  mask)
 {
-  if (button->priv->is_pressed)
-    return;
+  if (button->priv->pressed == 0)
+    st_widget_add_style_pseudo_class (ST_WIDGET (button), "active");
 
-  button->priv->is_pressed = TRUE;
-  st_widget_add_style_pseudo_class (ST_WIDGET (button), "active");
+  button->priv->pressed |= mask;
 }
 
 static void
-st_button_release (StButton *button,
-                   gboolean  clicked)
+st_button_release (StButton     *button,
+                   StButtonMask  mask,
+                   int           clicked_button)
 {
-  if (!button->priv->is_pressed)
+  button->priv->pressed &= ~mask;
+  if (button->priv->pressed != 0)
     return;
 
-  button->priv->is_pressed = FALSE;
   st_widget_remove_style_pseudo_class (ST_WIDGET (button), "active");
 
-  if (clicked)
+  if (clicked_button)
     {
       if (button->priv->is_toggle)
         st_button_set_checked (button, !button->priv->is_checked);
 
-      g_signal_emit (button, button_signals[CLICKED], 0);
+      g_signal_emit (button, button_signals[CLICKED], 0, clicked_button);
     }
 }
 
@@ -151,15 +157,18 @@ static gboolean
 st_button_button_press (ClutterActor       *actor,
                         ClutterButtonEvent *event)
 {
+  StButton *button = ST_BUTTON (actor);
+  StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button);
+
   st_widget_hide_tooltip (ST_WIDGET (actor));
 
-  if (event->button == 1)
+  if (button->priv->button_mask & mask)
     {
-      StButton *button = ST_BUTTON (actor);
+      if (button->priv->grabbed == 0)
+        clutter_grab_pointer (actor);
 
-      clutter_grab_pointer (actor);
-      button->priv->has_grab = TRUE;
-      st_button_press (button);
+      button->priv->grabbed |= mask;
+      st_button_press (button, mask);
 
       return TRUE;
     }
@@ -171,19 +180,19 @@ static gboolean
 st_button_button_release (ClutterActor       *actor,
                           ClutterButtonEvent *event)
 {
-  if (event->button == 1)
+  StButton *button = ST_BUTTON (actor);
+  StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button);
+
+  if (button->priv->button_mask & mask)
     {
-      StButton *button = ST_BUTTON (actor);
       gboolean is_click;
 
-      is_click = button->priv->has_grab && st_widget_get_hover (ST_WIDGET (button));
-      st_button_release (button, is_click);
+      is_click = button->priv->grabbed && st_widget_get_hover (ST_WIDGET (button));
+      st_button_release (button, mask, is_click ? event->button : 0);
 
-      if (button->priv->has_grab)
-        {
-          button->priv->has_grab = FALSE;
-          clutter_ungrab_pointer ();
-        }
+      button->priv->grabbed &= ~mask;
+      if (button->priv->grabbed == 0)
+        clutter_ungrab_pointer ();
 
       return TRUE;
     }
@@ -195,13 +204,18 @@ static gboolean
 st_button_key_press (ClutterActor    *actor,
                      ClutterKeyEvent *event)
 {
+  StButton *button = ST_BUTTON (actor);
+
   st_widget_hide_tooltip (ST_WIDGET (actor));
 
-  if (event->keyval == CLUTTER_KEY_space ||
-      event->keyval == CLUTTER_KEY_Return)
+  if (button->priv->button_mask & ST_BUTTON_ONE)
     {
-      st_button_press (ST_BUTTON (actor));
-      return TRUE;
+      if (event->keyval == CLUTTER_KEY_space ||
+          event->keyval == CLUTTER_KEY_Return)
+        {
+          st_button_press (button, ST_BUTTON_ONE);
+          return TRUE;
+        }
     }
 
   return FALSE;
@@ -211,16 +225,34 @@ static gboolean
 st_button_key_release (ClutterActor    *actor,
                        ClutterKeyEvent *event)
 {
-  if (event->keyval == CLUTTER_KEY_space ||
-      event->keyval == CLUTTER_KEY_Return)
+  StButton *button = ST_BUTTON (actor);
+
+  if (button->priv->button_mask & ST_BUTTON_ONE)
     {
-      st_button_release (ST_BUTTON (actor), TRUE);
-      return TRUE;
+      if (event->keyval == CLUTTER_KEY_space ||
+          event->keyval == CLUTTER_KEY_Return)
+        {
+          st_button_release (button, ST_BUTTON_ONE, 1);
+          return TRUE;
+        }
     }
 
   return FALSE;
 }
 
+static void
+st_button_key_focus_out (ClutterActor *actor)
+{
+  StButton *button = ST_BUTTON (actor);
+
+  /* If we lose focus between a key press and release, undo the press */
+  if ((button->priv->pressed & ST_BUTTON_ONE) &&
+      !(button->priv->grabbed & ST_BUTTON_ONE))
+    st_button_release (button, ST_BUTTON_ONE, 0);
+
+  CLUTTER_ACTOR_CLASS (st_button_parent_class)->key_focus_out (actor);
+}
+
 static gboolean
 st_button_enter (ClutterActor         *actor,
                  ClutterCrossingEvent *event)
@@ -230,12 +262,12 @@ st_button_enter (ClutterActor         *actor,
 
   ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->enter_event (actor, event);
 
-  if (button->priv->has_grab)
+  if (button->priv->grabbed)
     {
       if (st_widget_get_hover (ST_WIDGET (button)))
-        st_button_press (button);
+        st_button_press (button, button->priv->grabbed);
       else
-        st_button_release (button, FALSE);
+        st_button_release (button, button->priv->grabbed, 0);
     }
 
   return ret;
@@ -250,12 +282,12 @@ st_button_leave (ClutterActor         *actor,
 
   ret = CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
 
-  if (button->priv->has_grab)
+  if (button->priv->grabbed)
     {
       if (st_widget_get_hover (ST_WIDGET (button)))
-        st_button_press (button);
+        st_button_press (button, button->priv->grabbed);
       else
-        st_button_release (button, FALSE);
+        st_button_release (button, button->priv->grabbed, 0);
     }
 
   return ret;
@@ -274,6 +306,9 @@ st_button_set_property (GObject      *gobject,
     case PROP_LABEL:
       st_button_set_label (button, g_value_get_string (value));
       break;
+    case PROP_BUTTON_MASK:
+      st_button_set_button_mask (button, g_value_get_flags (value));
+      break;
     case PROP_TOGGLE_MODE:
       st_button_set_toggle_mode (button, g_value_get_boolean (value));
       break;
@@ -301,12 +336,18 @@ st_button_get_property (GObject    *gobject,
     case PROP_LABEL:
       g_value_set_string (value, priv->text);
       break;
+    case PROP_BUTTON_MASK:
+      g_value_set_flags (value, priv->button_mask);
+      break;
     case PROP_TOGGLE_MODE:
       g_value_set_boolean (value, priv->is_toggle);
       break;
     case PROP_CHECKED:
       g_value_set_boolean (value, priv->is_checked);
       break;
+    case PROP_PRESSED:
+      g_value_set_boolean (value, priv->pressed != 0);
+      break;
 
 
     default:
@@ -343,6 +384,7 @@ st_button_class_init (StButtonClass *klass)
   actor_class->button_release_event = st_button_button_release;
   actor_class->key_press_event = st_button_key_press;
   actor_class->key_release_event = st_button_key_release;
+  actor_class->key_focus_out = st_button_key_focus_out;
   actor_class->enter_event = st_button_enter;
   actor_class->leave_event = st_button_leave;
 
@@ -354,6 +396,13 @@ st_button_class_init (StButtonClass *klass)
                                NULL, G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 
+  pspec = g_param_spec_flags ("button-mask",
+                              "Button mask",
+                              "Which buttons trigger the 'clicked' signal",
+                              ST_TYPE_BUTTON_MASK, ST_BUTTON_ONE,
+                              G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class, PROP_BUTTON_MASK, pspec);
+
   pspec = g_param_spec_boolean ("toggle-mode",
                                 "Toggle Mode",
                                 "Enable or disable toggling",
@@ -367,23 +416,30 @@ st_button_class_init (StButtonClass *klass)
                                 FALSE, G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class, PROP_CHECKED, pspec);
 
+  pspec = g_param_spec_boolean ("pressed",
+                                "Pressed",
+                                "Indicates if the button is pressed in",
+                                FALSE, G_PARAM_READABLE);
+  g_object_class_install_property (gobject_class, PROP_PRESSED, pspec);
+
 
   /**
    * StButton::clicked:
    * @button: the object that received the signal
+   * @clicked_button: the mouse button that was used
    *
    * Emitted when the user activates the button, either with a mouse press and
    * release or with the keyboard.
    */
-
   button_signals[CLICKED] =
     g_signal_new ("clicked",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (StButtonClass, clicked),
                   NULL, NULL,
-                  _st_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
+                  _st_marshal_VOID__INT,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_INT);
 }
 
 static void
@@ -391,6 +447,7 @@ st_button_init (StButton *button)
 {
   button->priv = ST_BUTTON_GET_PRIVATE (button);
   button->priv->spacing = 6;
+  button->priv->button_mask = ST_BUTTON_ONE;
 
   clutter_actor_set_reactive (CLUTTER_ACTOR (button), TRUE);
   st_widget_set_track_hover (ST_WIDGET (button), TRUE);
@@ -431,7 +488,7 @@ st_button_new_with_label (const gchar *text)
  *
  * Returns: the text for the button. This must not be freed by the application
  */
-G_CONST_RETURN gchar *
+const gchar *
 st_button_get_label (StButton *button)
 {
   g_return_val_if_fail (ST_IS_BUTTON (button), NULL);
@@ -487,6 +544,42 @@ st_button_set_label (StButton    *button,
   g_object_notify (G_OBJECT (button), "label");
 }
 
+/**
+ * st_button_get_button_mask:
+ * @button: a #StButton
+ *
+ * Gets the mask of mouse buttons that @button emits the
+ * #StButton::clicked signal for.
+ *
+ * Returns: the mask of mouse buttons that @button emits the
+ * #StButton::clicked signal for.
+ */
+StButtonMask
+st_button_get_button_mask (StButton *button)
+{
+  g_return_val_if_fail (ST_IS_BUTTON (button), 0);
+
+  return button->priv->button_mask;
+}
+
+/**
+ * st_button_set_button_mask:
+ * @button: a #Stbutton
+ * @mask: the mask of mouse buttons that @button responds to
+ *
+ * Sets which mouse buttons @button emits #StButton::clicked for.
+ */
+void
+st_button_set_button_mask (StButton     *button,
+                           StButtonMask  mask)
+{
+  g_return_if_fail (ST_IS_BUTTON (button));
+
+  button->priv->button_mask = mask;
+
+  g_object_notify (G_OBJECT (button), "button-mask");
+}
+
 /**
  * st_button_get_toggle_mode:
  * @button: a #StButton
@@ -564,3 +657,29 @@ st_button_set_checked (StButton *button,
 
   g_object_notify (G_OBJECT (button), "checked");
 }
+
+/**
+ * st_button_fake_release:
+ * @button: an #StButton
+ *
+ * If this widget is holding a pointer grab, this function will
+ * will ungrab it, and reset the pressed state.  The effect is
+ * similar to if the user had released the mouse button, but without
+ * emitting the clicked signal.
+ *
+ * This function is useful if for example you want to do something
+ * after the user is holding the mouse button for a given period of
+ * time, breaking the grab.
+ */
+void
+st_button_fake_release (StButton *button)
+{
+  if (button->priv->pressed)
+    st_button_release (button, button->priv->pressed, 0);
+
+  if (button->priv->grabbed)
+    {
+      button->priv->grabbed = 0;
+      clutter_ungrab_pointer ();
+    }
+}
index 15a6983dd0d142c1fc42ff327225cee90430c174..23ae81bd19bccf9fbf0b7e6aace300bd65be105f 100644 (file)
@@ -68,17 +68,39 @@ struct _StButtonClass
 
 GType st_button_get_type (void) G_GNUC_CONST;
 
-StWidget *            st_button_new             (void);
-StWidget *            st_button_new_with_label  (const gchar *text);
-G_CONST_RETURN gchar *st_button_get_label       (StButton    *button);
-void                  st_button_set_label       (StButton    *button,
-                                                 const gchar *text);
-void                  st_button_set_toggle_mode (StButton    *button,
-                                                 gboolean     toggle);
-gboolean              st_button_get_toggle_mode (StButton    *button);
-void                  st_button_set_checked     (StButton    *button,
-                                                 gboolean     checked);
-gboolean              st_button_get_checked     (StButton    *button);
+StWidget    *st_button_new             (void);
+StWidget    *st_button_new_with_label  (const gchar  *text);
+const gchar *st_button_get_label       (StButton     *button);
+void         st_button_set_label       (StButton     *button,
+                                        const gchar  *text);
+void         st_button_set_toggle_mode (StButton     *button,
+                                        gboolean      toggle);
+gboolean     st_button_get_toggle_mode (StButton     *button);
+void         st_button_set_checked     (StButton     *button,
+                                        gboolean      checked);
+gboolean     st_button_get_checked     (StButton     *button);
+
+void         st_button_fake_release    (StButton     *button);
+
+/**
+ * StButtonMask:
+ * @ST_BUTTON_ONE: button 1 (left)
+ * @ST_BUTTON_TWO: button 2 (middle)
+ * @ST_BUTTON_THREE: button 3 (right)
+ *
+ * A mask representing which mouse buttons an StButton responds to.
+ */
+typedef enum {
+  ST_BUTTON_ONE   = (1 << 0),
+  ST_BUTTON_TWO   = (1 << 1),
+  ST_BUTTON_THREE = (1 << 2),
+} StButtonMask;
+
+#define ST_BUTTON_MASK_FROM_BUTTON(button) (1 << ((button) - 1))
+
+void         st_button_set_button_mask (StButton     *button,
+                                        StButtonMask  mask);
+StButtonMask st_button_get_button_mask (StButton     *button);
 
 G_END_DECLS
 
diff --git a/src/st/st-clickable.c b/src/st/st-clickable.c
deleted file mode 100644 (file)
index 5787aaf..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * st-clickable.h: A bin with methods and properties useful for implementing buttons
- *
- * Copyright 2009, 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:st-clickable
- * @short_description: A bin with methods and properties useful for implementing buttons
- *
- * A #StBin subclass which translates lower-level Clutter button events
- * into higher level properties which are useful for implementing "button-like"
- * actors.
- */
-
-#include "st-clickable.h"
-
-#include "st-private.h"
-
-G_DEFINE_TYPE (StClickable, st_clickable, ST_TYPE_BIN);
-
-struct _StClickablePrivate {
-  gboolean active;
-  gboolean held;
-  gboolean pressed;
-
-  guint initiating_button;
-};
-
-/* Signals */
-enum
-{
-  CLICKED,
-  LAST_SIGNAL
-};
-
-enum {
-  PROP_0,
-
-  PROP_ACTIVE,
-  PROP_HELD,
-  PROP_PRESSED
-};
-
-static guint st_clickable_signals [LAST_SIGNAL] = { 0 };
-
-static void
-sync_pseudo_class (StClickable *self)
-{
-  if (self->priv->pressed || self->priv->active)
-    st_widget_add_style_pseudo_class (ST_WIDGET (self), "pressed");
-  else
-    st_widget_remove_style_pseudo_class (ST_WIDGET (self), "pressed");
-}
-
-static void
-set_active (StClickable  *self,
-            gboolean      active)
-{
-  if (self->priv->active == active)
-    return;
-  self->priv->active = active;
-  sync_pseudo_class (self);
-  g_object_notify (G_OBJECT (self), "active");
-}
-
-static void
-set_pressed (StClickable  *self,
-             gboolean      pressed)
-{
-  if (self->priv->pressed == pressed)
-    return;
-  self->priv->pressed = pressed;
-  sync_pseudo_class (self);
-  g_object_notify (G_OBJECT (self), "pressed");
-}
-
-static gboolean
-st_clickable_enter_event (ClutterActor         *actor,
-                          ClutterCrossingEvent *event)
-{
-  StClickable *self = ST_CLICKABLE (actor);
-  gboolean result;
-
-  g_object_freeze_notify (G_OBJECT (actor));
-
-  result = CLUTTER_ACTOR_CLASS (st_clickable_parent_class)->enter_event (actor, event);
-
-  /* We can't just assume get_hover() is TRUE; see st_widget_enter(). */
-  set_pressed (self, self->priv->held && st_widget_get_hover (ST_WIDGET (actor)));
-
-  g_object_thaw_notify (G_OBJECT (actor));
-
-  return result;
-}
-
-static gboolean
-st_clickable_leave_event (ClutterActor         *actor,
-                              ClutterCrossingEvent *event)
-{
-  StClickable *self = ST_CLICKABLE (actor);
-  gboolean result;
-
-  g_object_freeze_notify (G_OBJECT (actor));
-
-  result = CLUTTER_ACTOR_CLASS (st_clickable_parent_class)->leave_event (actor, event);
-
-  /* As above, we can't just assume get_hover() is FALSE. */
-  set_pressed (self, self->priv->held && st_widget_get_hover (ST_WIDGET (actor)));
-
-  g_object_thaw_notify (G_OBJECT (actor));
-
-  return result;
-}
-
-static gboolean
-st_clickable_button_press_event (ClutterActor       *actor,
-                                 ClutterButtonEvent *event)
-{
-  StClickable *self = ST_CLICKABLE (actor);
-
-  if (event->click_count != 1)
-    return FALSE;
-
-  if (self->priv->held)
-    return TRUE;
-
-  if (!clutter_actor_contains (actor, event->source))
-    return FALSE;
-
-  self->priv->held = TRUE;
-  self->priv->initiating_button = event->button;
-  clutter_grab_pointer (CLUTTER_ACTOR (self));
-
-  set_pressed (self, TRUE);
-
-  return TRUE;
-}
-
-static gboolean
-st_clickable_button_release_event (ClutterActor       *actor,
-                                   ClutterButtonEvent *event)
-{
-  StClickable *self = ST_CLICKABLE (actor);
-
-  if (event->button != self->priv->initiating_button || event->click_count != 1)
-    return FALSE;
-
-  if (!self->priv->held)
-    return TRUE;
-
-  self->priv->held = FALSE;
-  clutter_ungrab_pointer ();
-
-  if (!clutter_actor_contains (actor, event->source))
-    return FALSE;
-
-  set_pressed (self, FALSE);
-
-  g_signal_emit (G_OBJECT (self), st_clickable_signals[CLICKED], 0, event);
-
-  return TRUE;
-}
-
-static gboolean
-st_clickable_key_press_event (ClutterActor    *actor,
-                              ClutterKeyEvent *event)
-{
-  StClickable *self = ST_CLICKABLE (actor);
-
-  if (event->keyval == CLUTTER_KEY_space ||
-      event->keyval == CLUTTER_KEY_Return)
-    {
-      set_pressed (self, TRUE);
-      return TRUE;
-    }
-  return FALSE;
-}
-
-static gboolean
-st_clickable_key_release_event (ClutterActor    *actor,
-                                ClutterKeyEvent *event)
-{
-  StClickable *self = ST_CLICKABLE (actor);
-
-  if (event->keyval != CLUTTER_KEY_space &&
-      event->keyval != CLUTTER_KEY_Return)
-    return FALSE;
-
-  set_pressed (self, FALSE);
-
-  g_signal_emit (G_OBJECT (self), st_clickable_signals[CLICKED], 0, event);
-  return TRUE;
-}
-
-/**
- * st_clickable_fake_release:
- * @box:
- *
- * If this widget is holding a pointer grab, this function will
- * will ungrab it, and reset the pressed state.  The effect is
- * similar to if the user had released the mouse button, but without
- * emitting the clicked signal.
- *
- * This function is useful if for example you want to do something after the user
- * is holding the mouse button for a given period of time, breaking the
- * grab.
- */
-void
-st_clickable_fake_release (StClickable *self)
-{
-  if (!self->priv->held)
-    return;
-
-  self->priv->held = FALSE;
-  clutter_ungrab_pointer ();
-
-  set_pressed (self, FALSE);
-}
-
-static void
-st_clickable_set_property (GObject         *object,
-                           guint            prop_id,
-                           const GValue    *value,
-                           GParamSpec      *pspec)
-{
-  StClickable *self = ST_CLICKABLE (object);
-
-  switch (prop_id)
-    {
-    case PROP_ACTIVE:
-      set_active (self, g_value_get_boolean (value));
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-static void
-st_clickable_get_property (GObject         *object,
-                           guint            prop_id,
-                           GValue          *value,
-                           GParamSpec      *pspec)
-{
-  StClickable *self = ST_CLICKABLE (object);
-
-  switch (prop_id)
-    {
-    case PROP_ACTIVE:
-      g_value_set_boolean (value, self->priv->active);
-      break;
-    case PROP_HELD:
-      g_value_set_boolean (value, self->priv->held);
-      break;
-    case PROP_PRESSED:
-      g_value_set_boolean (value, self->priv->pressed);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-static void
-st_clickable_class_init (StClickableClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
-  gobject_class->get_property = st_clickable_get_property;
-  gobject_class->set_property = st_clickable_set_property;
-
-  actor_class->enter_event = st_clickable_enter_event;
-  actor_class->leave_event = st_clickable_leave_event;
-  actor_class->button_press_event = st_clickable_button_press_event;
-  actor_class->button_release_event = st_clickable_button_release_event;
-  actor_class->key_press_event = st_clickable_key_press_event;
-  actor_class->key_release_event = st_clickable_key_release_event;
-
-  /**
-   * StClickable::clicked
-   * @box: The #StClickable
-   *
-   * This signal is emitted when the button should take the action
-   * associated with button click+release.
-   */
-  st_clickable_signals[CLICKED] =
-    g_signal_new ("clicked",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__BOXED,
-                  G_TYPE_NONE, 1, CLUTTER_TYPE_EVENT);
-
-  /**
-   * StClickable:active
-   *
-   * The property allows the button to be used as a "toggle button"; it's up to the
-   * application to update the active property in response to the activate signal;
-   * it doesn't happen automatically.
-   */
-  g_object_class_install_property (gobject_class,
-                                   PROP_ACTIVE,
-                                   g_param_spec_boolean ("active",
-                                                         "Active",
-                                                         "Whether the button persistently active",
-                                                         FALSE,
-                                                         G_PARAM_READWRITE));
-
-  /**
-   * StClickable:held
-   *
-   * This property tracks whether the button has the pointer grabbed,
-   * whether or not the pointer is currently hovering over the button.
-   */
-  g_object_class_install_property (gobject_class,
-                                   PROP_HELD,
-                                   g_param_spec_boolean ("held",
-                                                         "Held state",
-                                                         "Whether the mouse button is currently pressed",
-                                                         FALSE,
-                                                         G_PARAM_READABLE));
-
-  /**
-   * StClickable:pressed
-   *
-   * This property tracks whether the button should have a "pressed in"
-   * effect.
-   */
-  g_object_class_install_property (gobject_class,
-                                   PROP_PRESSED,
-                                   g_param_spec_boolean ("pressed",
-                                                         "Pressed state",
-                                                         "Whether the button is currently pressed",
-                                                         FALSE,
-                                                         G_PARAM_READABLE));
-
-  g_type_class_add_private (gobject_class, sizeof (StClickablePrivate));
-}
-
-static void
-st_clickable_init (StClickable *self)
-{
-  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ST_TYPE_CLICKABLE,
-                                            StClickablePrivate);
-  st_widget_set_track_hover (ST_WIDGET (self), TRUE);
-}
diff --git a/src/st/st-clickable.h b/src/st/st-clickable.h
deleted file mode 100644 (file)
index 2f1c3b0..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * st-clickable.h: A bin with methods and properties useful for implementing buttons
- *
- * Copyright 2009, 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __ST_CLICKABLE_H__
-#define __ST_CLICKABLE_H__
-
-#include "st-bin.h"
-
-#define ST_TYPE_CLICKABLE                 (st_clickable_get_type ())
-#define ST_CLICKABLE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), ST_TYPE_CLICKABLE, StClickable))
-#define ST_CLICKABLE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), ST_TYPE_CLICKABLE, StClickableClass))
-#define ST_IS_CLICKABLE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ST_TYPE_CLICKABLE))
-#define ST_IS_CLICKABLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), ST_TYPE_CLICKABLE))
-#define ST_CLICKABLE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), ST_TYPE_CLICKABLE, StClickableClass))
-
-typedef struct _StClickable        StClickable;
-typedef struct _StClickableClass   StClickableClass;
-
-typedef struct _StClickablePrivate StClickablePrivate;
-
-struct _StClickable
-{
-    StBin parent;
-
-    StClickablePrivate *priv;
-};
-
-struct _StClickableClass
-{
-    StBinClass parent_class;
-};
-
-GType st_clickable_get_type (void) G_GNUC_CONST;
-
-void st_clickable_fake_release (StClickable *box);
-
-#endif /* __ST_CLICKABLE_H__ */
index 9b3bed671e9ac7394a03c5a994a4b5b4146aaa88..69b75cc921ea5797436f955f2daecfd7b9b673d8 100644 (file)
@@ -2,6 +2,7 @@ VOID:OBJECT
 VOID:VOID
 VOID:PARAM
 VOID:POINTER
+VOID:INT
 VOID:UINT
 VOID:UINT,UINT
 VOID:OBJECT,OBJECT